// -----------------------------------------------------------------------
//  <copyright file="UpdateUserCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/10 16:07:27</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Identity.Domain.Entities;
using DaprPlus.Identity.Domain.IntegrationEvents;

using DaprPlus.Identity.Application.Identity.Users.Queries;

using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;

namespace DaprPlus.Identity.Application.Identity.Users.Commands;

[AuthConfig(typeof(User), ResourceAccessType.RoleLimit, "Update")]
public class UpdateUserCommand : IRequest<ApiResult>, ICommand
{
    public required UserInDto[] Dtos { get; set; }
}

public class UpdateUserCommandHandler(IServiceProvider provider)
    : IRequestHandler<UpdateUserCommand, ApiResult>
{
    public async Task<ApiResult> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
    {
        var repository = provider.GetRepository<User>();
        var userManager = provider.GetRequiredService<UserManager<User>>();
        var updatedUsers = new List<UserRecord>();

        foreach (var dto in request.Dtos)
        {
            var entity = await repository.FindAsync(dto.Id, cancellationToken);
            if (entity == null)
            {
                return new ApiResult(ApiResultType.Error, $"编号为 {dto.Id} 的用户信息不存在");
            }

            // 如果密码不为空，则更新密码
            if (!string.IsNullOrEmpty(dto.Password))
            {
                var token = await userManager.GeneratePasswordResetTokenAsync(entity);
                var result = await userManager.ResetPasswordAsync(entity, token, dto.Password);
                if (!result.Succeeded)
                {
                    return new ApiResult(ApiResultType.Error, result.Errors.First().Description);
                }
            }

            entity = dto.MapTo(entity);
            var updateResult = await userManager.UpdateAsync(entity);
            if (!updateResult.Succeeded)
            {
                return new ApiResult(ApiResultType.Error, updateResult.Errors.First().Description);
            }

            var spec = new UserByIdSpec<User>(entity.Id);
            entity = await repository.GetAsync(spec, cancellationToken);
            if (entity != null)
            {
                updatedUsers.Add(new UserRecord(entity.Id, entity.UserName, entity.NickName ?? entity.UserName, entity.IsLocked));
            }
        }

        var @event = new UserUpdatedIntegrationEvent([.. updatedUsers]);
        var uow = provider.GetUnitOfWork();
        uow.AddIntegrationEvent(@event);

        var userNames = updatedUsers.ExpandAndToString(m => m.NickName);
        return new ApiResult(ApiResultType.Success, $"用户 {userNames} 更新成功");
    }
}

